//Scheduled Task Hunt

DeviceEvents

| where DeviceName matches regex @"^naming.convention" //scoping for our devices

    and ActionType matches regex @"^ScheduledTask"

// parse

| extend parseme= parse_json(AdditionalFields)

| extend TaskName=tostring(parseme.TaskName),

    TaskContentRaw = tostring(parseme.TaskContent)

| extend TaskContent = parse_json(TaskContentRaw)

| extend Trigger = tostring(bag_keys(TaskContent.Triggers)[0]),

    Command = tostring(TaskContent.Actions.Exec.Command)

// ParsedFields parses the outer JSON (AdditionalFields).

// TaskContentRaw extracts the stringified JSON from TaskContent.

// TaskContent parses that string into a dynamic object.

// Trigger gets the first key from the Triggers object (e.g., CalendarTrigger).

// Command extracts the actual command string.

// -- Filter --

| where not(TaskName matches regex @"redacted")

    and TaskName !in~("redacted")

| project Timestamp, DeviceName, TaskName, ActionType, Trigger, Command, Username=InitiatingProcessAccountName

| sort by Timestamp desc
 